﻿//////// Constants
var BLOCK_COLOR = "#1100FF";
var BACKGROUND_COLOR = "#C9D0DA";
var GAME_BOARD_HEIGHT = 30;
var GAME_BOARD_WIDTH = 40;
var TOKEN_SIZE = 20;
var LARGE_TOKEN_SIZE = 200;
var UPDATE_FPS_STEP = 40;
////////////////////////////////

//////// Global Variables
var FPS_COUNTER = 0;
var gameBoard;
var clientGame = null;
var user = new User();
var testTime;
var deathSound, gameOverSound, userJoinedSound, userLeftSound;
var soundPlayer = new SoundPlayer();
var fireworkMaker = new FireworkMaker();
var gameInProgress = false;
////////////////////////////////

//////Setup
$(document).ready(function () {
    var r, c;
    var $divs = $("#GameBoard div.boardPiece");
    gameBoard = new Array();

    for (r = 0; r < GAME_BOARD_HEIGHT; r++) {
        gameBoard[r] = new Array();
        for (c = 0; c < GAME_BOARD_WIDTH; c++) {
            gameBoard[r][c] = $($divs.get((r * GAME_BOARD_WIDTH) + c));
        }
    }

    $("#StartGameButton").click(startGame);
    $("#RestartGameButton").click(restartGame);
    $("#GenerateBoardButton").click(generateBoard);
    $("#GenerateLevelButton").click(generateLevel);
    $("#ColorPicker").ColorPicker({ flat: true, onChange: colorPickerChange });
    $(".loginOption").click(loginOption_Click);
    $(".unlocked").live("click", lockGame);
    $(".locked").live("click", unlockGame);
    $("#ChatMessage").autosize();
    $("#UserNameTextBox").keypress(userName_Keypress);
});
////////////////////////////////

//////Connection & Disconnecting
function joinGame() {
    clientGame = new ClientGame(user);
    clientGame.gameBoardUpdated = gameBoardUpdated;
    clientGame.messageReceived = messageReceived;
    clientGame.loginSuccess = loginSuccess;
    clientGame.loginFailure = loginFailure;
    clientGame.userJoined = userJoined;
    clientGame.userLeft = userLeft;
    clientGame.playerDied = playerDied;
    clientGame.gameOver = gameOver;
    clientGame.gameStarted = gameStarted;
    clientGame.gameRestarted = gameRestarted;
    clientGame.hostGranted = hostGranted;
    clientGame.gameLocked = gameLocked;
    clientGame.gameUnlocked = gameUnlocked;
    clientGame.connect();
}

function startGame() {
    var alienInterval = parseInt($("#AlienInterval").val(), 10);
    var hunterInterval = parseInt($("#HunterInterval").val(), 10);
    var botInterval = parseInt($("#BotInterval").val(), 10);
    var aiAlienBots = parseInt($("#AlienBots").val(), 10);

    if (isNaN(alienInterval) || isNaN(hunterInterval) || isNaN(aiAlienBots) || isNaN(botInterval)) {
        alert("incorrect intervals");
    }
    else {
        clientGame.startGame(alienInterval, hunterInterval, botInterval, aiAlienBots);
        $(".hostControls").addClass("displayNone");
        $(".hostGameInProgressControls").removeClass("displayNone");
    }
}

function restartGame() {
    clientGame.restartGame();
}

function generateBoard() {
    var fillFactor = $("#FillFactor").val();
    if (isNaN(fillFactor) || fillFactor <= 0.1 || fillFactor >= 0.8) {
        alert("invalid fill factor. must be between 0.1 & 0.8");
    }
    else {
        clientGame.generateBoard(fillFactor);
    }
}

function generateLevel() {
    var levelNumber = $("#LevelNumber").val();
    if (levelNumber == 1 || levelNumber == 2 || levelNumber == 3) {
        clientGame.generateLevel(levelNumber);
    }
    else {
        alert("invalid level. must be between 1, 2 or 3");
    }
}

function gameStarted() {
    gameInProgress = true;
    $("#StartGameButton, .intervalTextBoxWrapper").addClass("displayNone");
    soundPlayer.gameStarted();
}

function gameRestarted() {
    alert("Game has been restarted");
    window.location.href = window.location.href;
}

function gameLocked() {
    $(".unlocked").addClass("locked").removeClass("unlocked");
}

function gameUnlocked() {
    $(".locked").addClass("unlocked").removeClass("locked");
}

///////////////////////

///////Joining and Leaving
function userJoined(user) {
    //Don't handle bots at all
    if (!user.bot) {
        //Don't handle yourself
        if (user.id != clientGame.getMyUser().id) {
            $("#ListOfUsers li.noUsersUser").remove();
            $existingUser = $("#ListOfUsers li[data-userName='" + user.userName + "']");
            if ($existingUser.length > 0) {
                $existingUser.removeClass("disconnected");
            }
            else {
                $("#ListOfUsers").append(makeUserRow(user));
            }
        }
        soundPlayer.userJoined();
    }
}

function userLeft(user) {
    $("#ListOfUsers li[data-userName='" + user.userName + "']").addClass("disconnected");
    soundPlayer.userLeft();
}

function makeUserRow(user) {
    var html = $("<li data-userName=\"" + user.userName + "\" data-userID=\"" + user.id + "\"><span>" + user.userName + "</span></li>");
    $(html).prepend(getUserToken(user, TOKEN_SIZE));
    return html;
}

function playerDied(userId) {
    if (userId > 0) {
        soundPlayer.hunterDied();
    }
    else {
        soundPlayer.alienDied();
    }
}

function gameOver(aliensWon) {
    var iAmAlien = clientGame.getMyUser().alien;
    if (aliensWon == iAmAlien) {
        fireworkMaker.makeFireworks();
    }
    else {
        soundPlayer.gameOver();
    }
}
///////////////////////////////////

//////////Login
function loginOption_Click() {
    user.alien = $(this).attr("data-tokenType") === "Alien";
    $("#UserTokenWrapper").html(getUserToken(user, LARGE_TOKEN_SIZE));

    $("#UserNameDialog").dialog({
        width: 650,
        title: "Choose a user name",
        buttons: {
            "Submit": userNameSelect_Click,
            "Cancel": function () {
                $(this).dialog("close");
            }
        }
    });
}

function userName_Keypress(e) {
    var k = e.keyCode || e.which;
    if (k == 13) {
        userNameSelect_Click();
    }
}

function userNameSelect_Click() {
    if ($("#UserNameTextBox").val().length > 0) {
        user.userName = $("#UserNameTextBox").val();
        joinGame();
    }
    else {
        loginFailure("You must choose a username");
    }
}

function loginSuccess(updates, id) {
    clientGame.setMyId(id);
    if (clientGame.getNumberOfUsers() > 1) {
        var $html = $("<div>");

        for (var key in clientGame.getUsers()) {
            if (key != clientGame.getMyUser().id) {
                $html.prepend(makeUserRow(clientGame.getUsers()[key]));
            }
        }

        $("#ListOfUsers").contents().replaceWith($html.contents());
    }

    gameBoardUpdated(updates);

    $("#MyUserName").html(clientGame.getMyUser().userName);
    $("#UserNameHeader").removeClass("visibilityHidden");
    $("#UserNameDialog").dialog("close");
    $("#Login").addClass("displayNone");
    $("#GameBoard").removeClass("displayNone");
    $("#ChatMessage").keypress(chatMessage_KeyPress);
}

function lockGame() {
    clientGame.lockGame();
}

function unlockGame() {
    clientGame.unlockGame();
}

function hostGranted(userId) {
    if (clientGame.getMyUser().id == userId) {
        if (gameInProgress) {
            $(".hostGameInProgressControls").removeClass("displayNone");
        }
        else {
            $(".hostControls").removeClass("displayNone");
        }
        $(".hostUniversalControls").removeClass("displayNone");
    }
}

function loginFailure(error) {
    $("#LoginErrorMessage").html(error).removeClass("visibilityHidden");
}

function colorPickerChange(hsb, hex, rgb) {
    user.tokenColor = "#" + hex;
    $("#UserTokenWrapper").contents().replaceWith(getUserToken(user, LARGE_TOKEN_SIZE));
}
/////////////////////

//////Drawing Game Board
function gameBoardUpdated(updates, alienUpdate) {
    var i;

    for (i = 0; i < updates.length; i++) {
        var $gameBoardSquare = gameBoard[updates[i].r][updates[i].c];
        $gameBoardSquare.css("background", getBackground(updates[i].id));
        $gameBoardSquare.html(getContents(updates[i].id));
    }

    if (alienUpdate) {
        FPS_COUNTER++;
        if (FPS_COUNTER == UPDATE_FPS_STEP) {
            var newTime = new Date().getTime();
            var time = ((newTime - testTime) / UPDATE_FPS_STEP).toFixed(2);
            var fps = ((UPDATE_FPS_STEP * 1000) / (newTime - testTime)).toFixed(2);
            $("#TestDiv").html("time: " + time + "&nbsp;&nbsp;&nbsp;fps: " + fps);
            testTime = newTime;
            FPS_COUNTER = 0;
        }
    }
}

function getContents(id) {
    var contents;
    var user;

    if (id >= 10 || id <= -10) {
        user = clientGame.getUser(id);
        if (user) {
            contents = getUserToken(user, TOKEN_SIZE);
        }
        else {
            contents = "";
        }
    }
    else {
        contents = "";
    }

    return contents;
}

function getUserToken(user, size) {
    var $wrapper;
    if (user.alien) {
        $wrapper = $("#AlienLogin");
    }
    else {
        $wrapper = $("#HunterLogin");
    }

    var $svg = $wrapper.children("svg").clone();
    $svg.attr("width", size).attr("height", size).attr("viewbox", "0 0 " + size + " " + size);
    if (user.tokenColor != null) {
        $svg.children("[class='userControlled']").attr("fill", user.tokenColor);
    }
    return $svg.get(0);
}

function getBackground(gamePiece) {
    var color;

    if (gamePiece == 1) {
        color = BLOCK_COLOR;
    }
    else {
        color = BACKGROUND_COLOR;
    }

    return color;
}
///////////////////////////////////

///////Chat
function chatMessage_KeyPress(e) {
    if (e.which == 13) {
        var $chatMessageTextBox = $("#ChatMessage");
        var message = $chatMessageTextBox.val();
        if (message.length > 0) {
            //chatTestTime = new Date().getTime();
            clientGame.sendMessage(message);
            $chatMessageTextBox.val("");
        }
        e.preventDefault();
    }
}

function messageReceived(user, data) {
    //var time = new Date().getTime() - chatTestTime;
    //$("#TestDiv").html(time);
    $("#ChatArea").append(makeMessageRow(user, data)).scrollTop($("#ChatArea")[0].scrollHeight);
}

function makeMessageRow(user, message) {
    var html = $("<div class=\"userMessage\" data-userName=\"" + user.userName + "\"><span class=\"userName\">" + user.userName + ": </span><span class=\"messageData\">" + message + "</span></div>");
    $(html).prepend(getUserToken(user, TOKEN_SIZE));
    return html;
}
///////////////////////